package com.zshan.clinic.web.service;

import com.google.code.kaptcha.Producer;
import com.zshan.clinic.admin.entity.vo.ClinicInfoWebVo;
import com.zshan.clinic.admin.service.clinic.ClinicEmpService;
import com.zshan.clinic.admin.service.clinic.ClinicInfoService;
import com.zshan.clinic.common.constant.CommonConstant;
import com.zshan.clinic.common.enums.YesOrNoEnum;
import com.zshan.clinic.common.exception.BusinessFailException;
import com.zshan.clinic.common.util.file.FileUtils;
import com.zshan.clinic.common.util.redis.RedisUtil;
import com.zshan.clinic.common.util.string.StringUtil;
import com.zshan.clinic.common.util.token.JWTHS256;
import com.zshan.clinic.common.util.uuid.IdBuilder;
import com.zshan.clinic.database.model.ClinicEmp;
import com.zshan.clinic.database.model.ClinicInfo;
import com.zshan.clinic.web.constant.WebRedisKeyPrefix;
import com.zshan.clinic.web.entity.CaptchaImageVo;
import com.zshan.clinic.web.entity.UserInfo;
import com.zshan.clinic.web.entity.request.AccountLoginRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author lichen
 */
@Slf4j
@Service
public class LoginService {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ClinicInfoService clinicService;

    @Autowired
    private ClinicEmpService clinicEmpService;


    @Resource(name = "captchaProducer")
    private Producer captchaProducer;


    /**
     * 用户登录
     * @param loginRequest
     * @return
     */
    public ClinicInfoWebVo getBoardClinicInfo(AccountLoginRequest loginRequest) {
        if(!validateCaptcha(loginRequest.getCode(),loginRequest.getUuid())){
            throw new BusinessFailException("验证码错误！");
        }
        //1.根据用户名和密码查询用户
        ClinicEmp clinicEmp = clinicEmpService.getEmpByAccount(loginRequest.getPhone(),loginRequest.getPassword());
        if(clinicEmp == null){
            throw new BusinessFailException("用户不存在/账号密码错误");
        }
        if(YesOrNoEnum.NO.getValue().equals(clinicEmp.getIsAdmin())){
            throw new BusinessFailException("请使用管理账号进行授权操作！");
        }
        return clinicService.getClinicInfoForWeb(clinicEmp.getClinicId());
    }

    /**
     * 获取图形验证码
     * @return
     */
    public CaptchaImageVo captchaImage() {
        CaptchaImageVo captchaImageVo = new CaptchaImageVo();
        // 保存验证码信息
        String uuid = IdBuilder.getID();
        captchaImageVo.setUuid(uuid);
        String verifyKey = WebRedisKeyPrefix.USER_LOGIN_CAPTCHA_CODE_KEY + uuid;
        /**
         * 图形验证码
         */
        String capText = captchaProducer.createText();
        /**
         * 计算公式
         */
        String capStr = capText.substring(0, capText.lastIndexOf("@"));
        /**
         * 结果
         */
        String code = capText.substring(capText.lastIndexOf("@") + 1);
        redisUtil.set(verifyKey, code, CommonConstant.DEFAULT_200);
        captchaImageVo.setImg(FileUtils.toBase64DataUrl(captchaProducer.createImage(capStr)));
        log.info("获取图形验证码接口，capStr:{},code:{}",capStr,code);
        return captchaImageVo;
    }

    /**
     * 校验验证码
     *
     * @param code 验证码
     * @param uuid 唯一标识
     * @return 结果
     */
    public boolean validateCaptcha(String code, String uuid) {
        String verifyKey = WebRedisKeyPrefix.USER_LOGIN_CAPTCHA_CODE_KEY + uuid;
        String cacheCode = (String) redisUtil.get(verifyKey);
        if(StringUtil.isBlank(cacheCode) || !cacheCode.equals(code)){
            log.info("图形验证码失败，前端给的code:{},redis保存的code:{}",code,cacheCode);
            return false;
        }
        redisUtil.del(verifyKey);
        return true;
    }

    /**
     * 用户登录
     * @param loginRequest
     * @return
     */
    public UserInfo loginByAccount(AccountLoginRequest loginRequest) {
        if(!validateCaptcha(loginRequest.getCode(),loginRequest.getUuid())){
            throw new BusinessFailException("验证码错误！");
        }
        //1.根据用户名和密码查询用户
        ClinicEmp clinicEmp = clinicEmpService.getEmpByAccount(loginRequest.getPhone(),loginRequest.getPassword());
        if(clinicEmp == null){
            throw new BusinessFailException("用户不存在/账号密码错误");
        }
        //2.根据查到的用户信息获取诊所信息
        ClinicInfo clinicInfo = clinicService.getClinicById(clinicEmp.getClinicId());
        if(clinicInfo == null){
            throw new BusinessFailException("诊所不存在");
        }
        //3.登录成功生成token
        String token = JWTHS256.buildJWT(StringUtil.valueOf(clinicEmp.getEmpId()));
        UserInfo userInfo = new UserInfo(clinicEmp.getEmpId(),clinicEmp.getEmpName(),clinicEmp.getGender(),token,clinicEmp.getIsAdmin(),clinicInfo.getClinicId());
        redisUtil.set(String.format(WebRedisKeyPrefix.USER_TOKEN,token), userInfo, CommonConstant.DAY_2);
        return userInfo;
    }

    /**
     * 退出登录
     * @param token
     */
    public void logout(String token) {
        if(StringUtil.isNotBlank(token)){
            //删除redis缓存
            redisUtil.del(String.format(WebRedisKeyPrefix.USER_TOKEN,token));
        }
    }

}
